// 数据大屏-中间件
const request = require('request');
const UserLoginLog = require('../models/Common/UserLoginLog')
const Essay = require('../models/Blog/Essay')
const moment = require('moment');
moment.suppressDeprecationWarnings = true;
var EventProxy = require('eventproxy');
var ep = new EventProxy();
module.exports = options => {
    return async (req, res, next) => {
        // 获取当前信息
        const isUser =  req.user
    
        // 查询返回数据
        const dataScreenObj = {
            statis: '', // 访问统计
            weather:'', // 天气
            mapData:'', // 地图坐标数据
            classifyPieData:'', // 文章分类数量占比饼图
            paasVisitPieData: '', // 平台访问率对比饼图
            monthlyLineData:'',// 用户访问月度折线图
            regionalUsersBarData:'', // 区域用户量统计柱状图
            rankingList:'',// 文章访问量排行榜top20
            userLoginLogList:'' //用户登录日志
        }
        let userLoginLogList = await UserLoginLog.find() // 登陆记录列表
        let cityList = await getEntityByList(userLoginLogList,'userCity') // 用户所在城市列表
        let essayList = await Essay.find()  // 文章列表
        const { monthlyLine ,monthTotal,yearTotal} = await getMonthlyData(userLoginLogList) // 获取用户月度访问信息
        // 用户登录日志
        dataScreenObj.userLoginLogList = userLoginLogList.reverse()
        // 根据位置获取坐标，地图数据
        dataScreenObj.mapData = await getCoord(cityList)
        // 天气
        dataScreenObj.weather = await getWeather(isUser.userCity)
        // 文章分类数量占比饼图
        dataScreenObj.classifyPieData = await getEntityByList(essayList,'essayTypeName')
        // 平台访问率对比饼图
        dataScreenObj.paasVisitPieData = await getEntityByList(userLoginLogList,'passName')
        // 文章访问量排行榜top20
        dataScreenObj.rankingList = await getRanking(essayList)
        // 区域用户量统计柱状图
        dataScreenObj.regionalUsersBarData = await getbarData(cityList)
        // 用户访问月度折线图
        dataScreenObj.monthlyLineData = monthlyLine
        // 访问统计
        dataScreenObj.statis = [
            { name: '访问总量', num: userLoginLogList.length },
            { name: '当年总量', num: yearTotal},
            { name: '当月总量', num: monthTotal },
            { name: 'start', num: 2190 }
        ]
        // 绑定全部数据
        req.dataScreenObj = dataScreenObj
        await next()
    }
}


/**
 *@desc 查询数组中相同的属性数量值 
 *@param list [array] 需要 查询的数组
 *@param entity [String] 匹配的属性名
*/
async function getEntityByList(list,entity){
    let titleList = list.map(item => {
        return item[entity]
    })
    function getRepeatNum(){ return titleList.reduce(function(prev,next){ prev[next] = (prev[next] + 1) || 1; return prev; },{}); }
    let myObj = getRepeatNum()
    let winningList = [] // 列表包含数量
    for(let i in myObj){
        if(i){
            let obj = {
                name:i,
                value:myObj[i]
            }
            winningList.push(obj)
        }
    }
    return winningList
}
// 处理-柱状图数据
function getbarData(data){
    let option = {
        xAxisData:[],
        seriesData:[]
    }
    data.forEach((item,index)=>{
        option.xAxisData[index] = item.name
        option.seriesData[index] = item.value
    })
    return option
}

// 请求天气api接口
function getWeather(city){
    return new Promise((resolve, reject)=>{
        // 获取登录位置天气
        request({
            url:`http://wthrcdn.etouch.cn/weather_mini?city=${encodeURI(city || '北京')}`,
            gzip: true // 在线返回数据是gzip压缩过的
        }, async (error, response, body) => {
            if (!error && response.statusCode == 200) {
                resolve(JSON.parse(body).data)
            }
            //    dataScreenObj.weather = body // Show the HTML for the baidu homepage.
        }) 
    });
}
// 请求坐标api接口
function getCoord(addresses){
    return new Promise((resolve, reject)=>{
        // 获取登录位置坐标
        ep.after('getLocation', addresses.length, function(locations) {
            resolve(locations);
        })
        // 地区列表，多个数据
        addresses.forEach((item,index)=>{
            request({
                url:`http://api.map.baidu.com/geocoding/v3/?address=${encodeURI(item.name)}&output=json&ak=IjlQyeDxGb3QGxhcD7Wsik6UISYieSLt`,
                gzip: true // 在线返回数据是gzip压缩过的
            }, async (error, response, body) => {
                if (!error && response.statusCode == 200) {
                    const { lng, lat} = JSON.parse(body).result.location
                    ep.emit('getLocation', {name: item.name, value: [lng,lat,item.value]})
                }
                //    dataScreenObj.weather = body // Show the HTML for the baidu homepage.
            }) 
        })
    });
}
// 处理文章阅读量排行榜数据
function getRanking(essay){
    // 将文章列表按浏览量从高到低排序
    const newEssay = essay.sort((a,b)=>{
        return b.pageView - a.pageView 
    })
    // 截取前十数据
    const essayList =JSON.parse(JSON.stringify(newEssay.slice(0,16)))
    // 设置排行榜icon、背景色
    essayList.forEach((item,index)=>{
        item['background'] = (index % 2 === 0) ? "rgba(0,0,0,.4)" :  "rgba(0,0,0,.6)"
        switch (index){
            case 0 :
                item['icon'] = 'iconfont icon-first'
                break;
            case 1 :
                item['icon'] = 'iconfont icon-second'
                break;
            case 2 :
                item['icon'] = 'iconfont icon-third'
                break;
            default:
                item['icon'] = null
                item['ranking'] = index + 1
                break
        }
    })
    // 返回
    return essayList
}   
// 处理-用户访问月度数据
async function getMonthlyData(data){
    const newData = JSON.parse(JSON.stringify(data))
    // 获取最近12个月
    var option = [];
    var data = new Date();
    data.setMonth(data.getMonth()+1, 1)//获取到当前月份,设置月份
    for (var i = 0; i < 12; i++) {
        data.setMonth(data.getMonth() - 1);//每次循环一次 月份值减1
        var m = data.getMonth() + 1;
        m = m < 10 ? "0" + m : m;
        option.push({name:data.getFullYear() + "-" + (m),value:0})
    }
    // 将登录时间转换为月份
    await newData.forEach((item,index)=>{
        option.forEach(val=>{
            if(val.name === moment(item.loginTime).format('YYYY-MM')){
                val.value ++
            }
        })
    })
    option = option.reverse()
    // 将数据转化成折线图需要格式-返回
    const monthlyLine = await getbarData(option)
    // 预计访问率
    monthlyLine['predictData'] = []
    monthlyLine.seriesData.forEach((item,index)=>{
        monthlyLine['predictData'][index] = (Math.floor(Math.random()*(-5) + 10) * (item === 0 ? 1 : item))
    })  
    return {
        monthlyLine,  //月度折线图
        monthTotal:option[11].value,  // 当月访问总量
        yearTotal:monthlyLine.seriesData.reduce((a,b)=>a+b) // 当年访问总量
    }
}